package com.oss.config.filter;

import com.oss.common.BaseResponse;
import com.oss.config.ThreadContext;
import com.oss.entity.system.Token;
import com.oss.entity.system.User;
import com.oss.service.system.DictionaryService;
import com.oss.service.system.TokenService;
import com.oss.service.system.UserService;
import com.oss.util.TokenUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

@Component
public class TokenFilter extends OncePerRequestFilter {
    @Resource
    UserService userService;
    @Autowired
    TokenService tokenService;
    @Autowired
    TokenUtil tokenUtil;

    // 不需要认证的白名单路径
    private static final List<String> WHITELIST = Arrays.asList(
            ".*/oss/user/login",
            ".*/oss/dictionary/.*", // 网页端注册时查询数据字典
            ".*/oss/student/webRegister", // 网页端注册
            ".*/oss/dataImport/importTradeInfo", // 上传文件
            ".*/oss/doc/.*"
    );

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String path = request.getRequestURI();
        // 白名单放行
        if (WHITELIST.stream().anyMatch(path::matches) || isOutSystem(request)) {
            chain.doFilter(request, response);
            return;
        }
        // 获取请求头中的 Authorization
        String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (StringUtils.isBlank(authHeader)) {
            BaseResponse.tokenError(response,"缺少或无效的Token");
            return ;
        }
        String token = authHeader;
        try {
            // 先查询数据库的token是否存在 , 是否过期
            Token tokenEntity = tokenService.getTokenByTokenAndUserID(token);
            if (tokenEntity == null) {
                BaseResponse.tokenError(response,"Token不存在");
                return ;
            } else {
                boolean flag = tokenEntity.getExpirationTime().isAfter(LocalDateTime.now());
                if (flag == false){
                    BaseResponse.tokenError(response,"Token已过期");
                    return ;
                }
            }
            // 取出用户对应的信息, 存入上下文
            String userId = tokenEntity.getUserId();
            User user = userService.getById(userId);
            ThreadContext.setAuthorizeInfo(user);
            chain.doFilter(request, response);
        } catch (Exception e) {
            BaseResponse.tokenError(response,"Token解析异常");
            return ;
        }
    }

    /**
     * 是为外部接口
     * @param request
     * @return
     */
    private boolean isOutSystem(HttpServletRequest request) {
        // 外部请求头值
        String appidValue = "5c86bb8845f74d828e9f53f2938a27c2";
        // 外部接口请求头
        String appID = request.getHeader("appID");
        return appidValue.equals(appID);
    }
}
